{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 前期工作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "df = pd.read_csv(\"data/train_pp.csv\")\n",
    "important_num_cols = list(df.corr()[\"SalePrice\"][(\n",
    "    df.corr()[\"SalePrice\"] > 0.50) | (df.corr()[\"SalePrice\"] < -0.50)].index)\n",
    "cat_cols = [\"MSZoning\", \"Utilities\", \"BldgType\",\n",
    "            \"Heating\", \"KitchenQual\", \"SaleCondition\", \"LandSlope\"]\n",
    "important_cols = important_num_cols + cat_cols\n",
    "\n",
    "df = df[important_cols]\n",
    "X = df.drop(\"SalePrice\", axis=1)\n",
    "y = df[\"SalePrice\"]\n",
    "# One-Hot Encoding\n",
    "X = pd.get_dummies(X, columns=cat_cols)\n",
    "# Train-Test Split\n",
    "from sklearn.model_selection import train_test_split, cross_val_score\n",
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "    X, y, test_size=0.2, random_state=42)\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error\n",
    "# 评价函数\n",
    "\n",
    "\n",
    "def rmse_cv(model):\n",
    "    rmse = np.sqrt(-cross_val_score(model, X, y,\n",
    "                   scoring=\"neg_mean_squared_error\", cv=5)).mean()\n",
    "    return rmse\n",
    "\n",
    "\n",
    "def evaluation(y, predictions):\n",
    "    mae = mean_absolute_error(y, predictions)\n",
    "    mse = mean_squared_error(y, predictions)\n",
    "    rmse = np.sqrt(mean_squared_error(y, predictions))\n",
    "    r_squared = r2_score(y, predictions)\n",
    "    return mae, mse, rmse, r_squared\n",
    "\n",
    "\n",
    "# 标准化\n",
    "important_num_cols.remove(\"SalePrice\")\n",
    "\n",
    "scaler = StandardScaler()\n",
    "X[important_num_cols] = scaler.fit_transform(X[important_num_cols])\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型的训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 0, Loss: 8.174231469631195\n",
      "Epoch 1, Loss: 0.3688914179801941\n",
      "Epoch 2, Loss: 0.0696183443069458\n",
      "Epoch 3, Loss: 0.0\n",
      "Epoch 4, Loss: 0.0\n",
      "Epoch 5, Loss: 0.0\n",
      "Epoch 6, Loss: 0.0\n",
      "Epoch 7, Loss: 0.0\n",
      "Epoch 8, Loss: 0.0\n",
      "Epoch 9, Loss: 0.0\n",
      "Epoch 10, Loss: 0.0\n",
      "Epoch 11, Loss: 0.0\n",
      "Epoch 12, Loss: 0.0\n",
      "Epoch 13, Loss: 0.0\n",
      "Epoch 14, Loss: 0.0\n",
      "Epoch 15, Loss: 0.0\n",
      "Epoch 16, Loss: 0.0\n",
      "Epoch 17, Loss: 0.0\n",
      "Epoch 18, Loss: 0.0\n",
      "Epoch 19, Loss: 0.0\n",
      "Epoch 20, Loss: 0.0\n",
      "Epoch 21, Loss: 0.0\n",
      "Epoch 22, Loss: 0.0\n",
      "Epoch 23, Loss: 0.0\n",
      "Epoch 24, Loss: 0.0\n",
      "Epoch 25, Loss: 0.0\n",
      "Epoch 26, Loss: 0.0\n",
      "Epoch 27, Loss: 0.0\n",
      "Epoch 28, Loss: 0.0\n",
      "Epoch 29, Loss: 0.0\n",
      "Epoch 30, Loss: 0.0\n",
      "Epoch 31, Loss: 0.0\n",
      "Epoch 32, Loss: 0.0\n",
      "Epoch 33, Loss: 0.0\n",
      "Epoch 34, Loss: 0.0\n",
      "Epoch 35, Loss: 0.0\n",
      "Epoch 36, Loss: 0.0\n",
      "Epoch 37, Loss: 0.0\n",
      "Epoch 38, Loss: 0.0\n",
      "Epoch 39, Loss: 0.0\n",
      "Epoch 40, Loss: 0.0\n",
      "Epoch 41, Loss: 0.0\n",
      "Epoch 42, Loss: 0.0\n",
      "Epoch 43, Loss: 0.0\n",
      "Epoch 44, Loss: 0.0\n",
      "Epoch 45, Loss: 0.0\n",
      "Epoch 46, Loss: 0.0\n",
      "Epoch 47, Loss: 0.0\n",
      "Epoch 48, Loss: 0.0\n",
      "Epoch 49, Loss: 0.0\n",
      "Epoch 50, Loss: 0.0\n",
      "Epoch 51, Loss: 0.0\n",
      "Epoch 52, Loss: 0.0\n",
      "Epoch 53, Loss: 0.0\n",
      "Epoch 54, Loss: 0.0\n",
      "Epoch 55, Loss: 0.0\n",
      "Epoch 56, Loss: 0.0\n",
      "Epoch 57, Loss: 0.0\n",
      "Epoch 58, Loss: 0.0\n",
      "Epoch 59, Loss: 0.0\n",
      "Epoch 60, Loss: 0.0\n",
      "Epoch 61, Loss: 0.0\n",
      "Epoch 62, Loss: 0.0\n",
      "Epoch 63, Loss: 0.0\n",
      "Epoch 64, Loss: 0.0\n",
      "Epoch 65, Loss: 0.0\n",
      "Epoch 66, Loss: 0.0\n",
      "Epoch 67, Loss: 0.0\n",
      "Epoch 68, Loss: 0.0\n",
      "Epoch 69, Loss: 0.0\n",
      "Epoch 70, Loss: 0.0\n",
      "Epoch 71, Loss: 0.0\n",
      "Epoch 72, Loss: 0.0\n",
      "Epoch 73, Loss: 0.0\n",
      "Epoch 74, Loss: 0.0\n",
      "Epoch 75, Loss: 0.0\n",
      "Epoch 76, Loss: 0.0\n",
      "Epoch 77, Loss: 0.0\n",
      "Epoch 78, Loss: 0.0\n",
      "Epoch 79, Loss: 0.0\n",
      "Epoch 80, Loss: 0.0\n",
      "Epoch 81, Loss: 0.0\n",
      "Epoch 82, Loss: 0.0\n",
      "Epoch 83, Loss: 0.0\n",
      "Epoch 84, Loss: 0.0\n",
      "Epoch 85, Loss: 0.0\n",
      "Epoch 86, Loss: 0.0\n",
      "Epoch 87, Loss: 0.0\n",
      "Epoch 88, Loss: 0.0\n",
      "Epoch 89, Loss: 0.0\n",
      "Epoch 90, Loss: 0.0\n",
      "Epoch 91, Loss: 0.0\n",
      "Epoch 92, Loss: 0.0\n",
      "Epoch 93, Loss: 0.0\n",
      "Epoch 94, Loss: 0.0\n",
      "Epoch 95, Loss: 0.0\n",
      "Epoch 96, Loss: 0.0\n",
      "Epoch 97, Loss: 0.0\n",
      "Epoch 98, Loss: 0.0\n",
      "Epoch 99, Loss: 0.0\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error\n",
    "from sklearn.model_selection import train_test_split\n",
    "import numpy as np\n",
    "\n",
    "num_inputs = 2\n",
    "num_examples = 1000\n",
    "true_w = [2, -3.4]\n",
    "true_b = 4.2\n",
    "features = np.random.normal(0, 1, (num_examples, num_inputs))\n",
    "labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b\n",
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "    features, labels, test_size=0.25, random_state=0)\n",
    "train_data = torch.from_numpy(np.concatenate(\n",
    "    (X_train, y_train.reshape(-1, 1)), axis=1))\n",
    "n_feature = train_data.shape[1]\n",
    "\n",
    "\n",
    "class Regression(nn.Module):\n",
    "\n",
    "    def __init__(self, eps):\n",
    "        super(Regression, self).__init__()\n",
    "        self.w = nn.Parameter(torch.tensor(\n",
    "            np.random.normal(0, 0.01, (n_feature, 1))))\n",
    "        self.b = nn.Parameter(torch.zeros(1))\n",
    "        self.eps = eps\n",
    "\n",
    "    def forward(self, x):\n",
    "        w = self.w / self.w.norm()\n",
    "        x = torch.matmul(x, w) + self.b\n",
    "        return x[x > self.eps].sum() - x[x < -self.eps].sum()\n",
    "\n",
    "\n",
    "def perdict(train_data, test_data):\n",
    "    model = Regression(1)\n",
    "    opt = optim.SGD(model.parameters(), lr=0.01)\n",
    "    for i in range(500):\n",
    "        loss = model(train_data)\n",
    "        print(f'Epoch {i}, Loss: {loss}')\n",
    "        opt.zero_grad()\n",
    "        loss.backward()\n",
    "        opt.step()\n",
    "    yy = -(torch.matmul(test_data, model.w[:-1]) + model.b) / model.w[-1]\n",
    "    return yy.data\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 应用于未知数据并评价"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MAE: 53014.46901479441\n",
      "MSE: 5269373929.708357\n",
      "RMSE: 72590.45343368752\n",
      "R2 Score: 0.024477254360414147\n"
     ]
    }
   ],
   "source": [
    "\n",
    "y_perdict = perdict(train_data, torch.from_numpy(X_test))\n",
    "mae, mse, rmse, r_squared = evaluation(y_test, y_perdict)\n",
    "print(\"MAE:\", mae)\n",
    "print(\"MSE:\", mse)\n",
    "print(\"RMSE:\", rmse)\n",
    "print(\"R2 Score:\", r_squared)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "08260d92d3940e542e22a262135b7bde4ca9fdc24c8a80f681615fa4938938e4"
  },
  "kernelspec": {
   "display_name": "Python 3.9.7 64-bit",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
